<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>文件下载</title>
  <script src="../static/js/vue.global.js"></script>
  <script src="../static/js/axios.min.js"></script>
</head>
<body>
<div id="app">
  <div>
    <div>请先输入要下载的地址：</div>
    <input type="text" v-model="url">
  </div>
  <div>
    <div>请先输入要下载的文件名和格式：</div>
    <input type="text" v-model="name">
  </div>

  <h1>方式1：a标签下载</h1>
  <a :href="url" :download="name">1.png</a>
  <br>

  <h1>方式2：window.open()</h1>
  <button @click="download2">下载</button>

  <h1>方式3：location.href</h1>
  <button @click="download3">下载</button>

  <h1>方式4：请求服务器要求返回blob流，new Blob读取，js创建a标签下载</h1>
  <button @click="download4">下载</button>

  <h1>方式5：请求服务器要求返回arrayBuffer流，js创建a标签下载</h1>
  <button @click="download5">下载</button>
</div>
<script>
  const { createApp } = Vue;
  createApp({
    data() {
      return {
        name: 'xxx.jpeg',
        url: 'https://cdn.pixabay.com/photo/2022/09/20/20/22/blueberries-7468718__340.jpg',
      }
    },
    methods: {
      download2() {
        window.open(this.url)
      },
      download3() {
        location.href = this.url
      },
      async download4() {
        const res = await axios.get(this.url, {
          responseType: 'blob', // 也可以是'arraybuffer'-文件流
        });

        // res为接口返回数据，在请求接口的时候可进行鉴权
        if (!res) return;

        if ("msSaveOrOpenBlob" in navigator) {
          // IE及IE内核浏览器
          navigator.msSaveOrOpenBlob(res, this.name);
        } else {
          // 其他浏览器
          // new Blob()生成blob地址，可用于下载或预览
          let url = URL.createObjectURL(new Blob([res.data], { type: res.data.type}));
          let a = document.createElement("a");
          a.style.display = "none";
          a.href = url;
          a.download = this.name;
          a.click();

          // 内存释放
          a = null;
          URL.revokeObjectURL(url);
          console.log(url);
          url = null;
        }
      },
      async download5() {
        const res = await axios.get(this.url, {
          responseType: 'blob', // 也可以是'arraybuffer'-文件流
        });

        // res为接口返回数据，在请求接口的时候可进行鉴权
        if (!res) return;

        const fileReader = new FileReader();
        fileReader.readAsDataURL(res.data);
        let _this = this;
        fileReader.onload = function(result) {
          let a = document.createElement("a");
          let url = result.target.result; // 是个base64
          a.style.display = "none";
          a.href = url;
          a.download = _this.name;
          a.click();
          a = null;
          URL.revokeObjectURL(url); // 内存释放
          url = null;
        }
      }
    }
  }).mount('#app')
</script>
</body>
</html>
